package com.lyf.scm.plan.domain.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.GeneralCellWriteHandler;
import com.lyf.scm.plan.api.dto.*;
import com.lyf.scm.plan.domain.convertor.SalesPlanOtherConvertor;
import com.lyf.scm.plan.domain.remote.item.dto.SkuUnitDTO;
import com.lyf.scm.plan.domain.remote.item.facade.ItemCoreFacade;
import com.lyf.scm.plan.domain.repository.GmvTargetRepository;
import com.lyf.scm.plan.domain.repository.RoleAuthorityAreaRepository;
import com.lyf.scm.plan.domain.repository.SalesPlanOtherDifferinRespository;
import com.lyf.scm.plan.domain.repository.SalesPlanOtherRespository;
import com.lyf.scm.plan.domain.service.SalesPlanOtherDifferinService;
import com.lyf.scm.plan.insfrastructure.db.dataobject.DemandPlanDO;
import com.lyf.scm.plan.insfrastructure.db.dataobject.SalesPlanOtherDO;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * description:
 * 其他渠道计划_目标与销售计划差异serviceImpl
 *
 * @author: huangtao
 * @data: 2020/7/31
 */
@Slf4j
@Service
public class SalesPlanOtherDifferinServiceImpl implements SalesPlanOtherDifferinService {
    @Resource
    private ItemCoreFacade itemCoreFacade;
    @Resource
    private GmvTargetRepository gmvTargetRepository;
    @Resource
    private RoleAuthorityAreaRepository roleAuthorityAreaRepository;
    @Resource
    private SalesPlanOtherRespository salesPlanOtherRespository;
    @Resource
    private SalesPlanOtherConvertor salesPlanOtherConvertor;
    @Resource
    private SalesPlanOtherDifferinRespository salesPlanOtherDifferinRespository;


    /**
     * 按条件查询其他渠道计划_目标与销售计划差异（周）
     * 此页面的指标都是去别的表中取的，所以暂时不需要自己对应的表
     *
     * @param salesPlanOtherDTO
     * @return
     */
    @Override
    public PageInfo<SalesPlanOtherDifferinInfoDTO> listWeekBySelective(SalesPlanOtherDTO salesPlanOtherDTO) {
        //根据日期获取间隔日期集合,没有结束时间，默认14周
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(salesPlanOtherDTO.getStartTime(), CommonConstants.WEEK_SIZE);
        salesPlanOtherDTO.setWeekDateList(weekDates);
        salesPlanOtherDTO.setEndTime(MyDateUtil.getLastDate(null, weekDates));
        PageInfo<SalesPlanOtherDifferinInfoDTO> dtoPageInfo = new PageInfo<>();
        Long userId = salesPlanOtherDTO.getCreator();
        //获取当前用户角色权限
        List<RoleAuthorityAreaDTO> roleAreaList = roleAuthorityAreaRepository.listByUserId(userId);
        if (CollectionUtils.isEmpty(roleAreaList)) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        //渠道不为空为其他渠道计划用户
        roleAreaList = roleAreaList.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelCode())).collect(Collectors.toList());
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getChannelCode();
            channels.add(channel);
        });
        //高级搜索不选择渠道，查询用户对应渠道
        if (CollectionUtils.isEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            salesPlanOtherDTO.setChannelCodeList(channels);
        }
        //根据高级搜索条件查询分页后的某一页的需要查询指标的信息
        PageInfo<SalesPlanOtherDO> listPageInfo = null;//salesPlanOtherRespository.listWeekBySelective(salesPlanOtherDTO);
        List<SalesPlanOtherDO> list = listPageInfo.getList();
        if (CollectionUtils.isNotEmpty(list)) {
            //处理查询出来的条数和数据，查询明细指标的条件`
            SalesPlanOtherDO salesPlanOtherDO = this.dealData(list, salesPlanOtherDTO);
            List<SalesPlanOtherDTO> salesPlan = salesPlanOtherRespository.listSalesAndTargetDifferent(salesPlanOtherDO);
            //todo 大数据的数据暂时给死值
            salesPlan.forEach(item -> {
                item.setActualReceiveQty(new BigDecimal(423));
                item.setActualSalesQty(new BigDecimal(450));
                item.setConfirmAmount(item.getAllchannelConfirmedQty().multiply(BigDecimal.TEN));
                item.setActualSalesAmount(item.getActualSalesQty().multiply(BigDecimal.TEN));
            });
            if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOtherDTO.getUnitType())) {
                //获取对应的skuCode，换算单位使用
                List<String> skuCodeList = salesPlan.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
                //处理单位
                List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, salesPlanOtherDTO.getUnitType());
                //根据获取的换算比例计算指标数量
                this.calculationPro(salesPlan, skuUnitList);
            }
            //获取所有查询条件标识
            List<String> conditions = this.getConditions(salesPlanOtherDTO);
            //第二次查询明细的时候由于需要对skuCode进行换算，所以，查询的是所有的skuCode,因此需要分组为第一个分页查询出来的条数
            this.getGroupByKey(salesPlan, salesPlanOtherDTO.getSkuCodeList(), conditions);
            //将数据分组
            Map<String, List<SalesPlanOtherDTO>> listMap = salesPlan.stream().collect(Collectors.groupingBy(SalesPlanOtherDTO::getCondition, Collectors.toList()));
            List<SalesPlanOtherDifferinInfoDTO> targetList = this.getTargetList(listMap, salesPlanOtherDTO);

            //处理对应的GMV指标
            //Map<String, Map<Date, BigDecimal>> gmvTarget = this.dealGmvTarget(demandPlanDO, demandPlan);
            //this.putTargetInList(targetList,demandPlan ,gmvTarget ,weekDates , conditions)
            dtoPageInfo.setList(targetList);
            dtoPageInfo.setTotal(listMap.values().size());
        }
        return dtoPageInfo;
    }

    /**
     * 设置分组依据的key值
     *
     * @param salesPlan   需求计划dos
     * @param skuCodeList sku代码列表
     * @return {@link List<DemandPlanDTO>}
     */
    private List<SalesPlanOtherDTO> getGroupByKey(List<SalesPlanOtherDTO> salesPlan, List<String> skuCodeList, List<String> conditions) {
        salesPlan.forEach(item -> {
            StringBuilder keyStr = new StringBuilder();
            StringBuilder keys = new StringBuilder();
            keyStr.append(ObjectUtil.isNull(item.getSubChannelCode()) ? item.getChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getSubChannelCode()) ? item.getSubChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getPriCategoryCode()) ? item.getPriCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getSecCategoryCode()) ? item.getSecCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getTerCategoryCode()) ? item.getTerCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getProvinceCode()) ? item.getProvinceCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getCityCode()) ? item.getCityCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getCountyCode()) ? item.getCountyCode() : "");
            if (CollectionUtils.isNotEmpty(skuCodeList)) {
                keyStr.append(ObjectUtil.isNotNull(item.getSkuCode()) ? item.getSkuCode() : "");
            }
            keys.append(ObjectUtil.isNotNull(item.getPriCategoryCode()) ? item.getPriCategoryCode() : "");
            keys.append(ObjectUtil.isNotNull(item.getSecCategoryCode()) ? item.getSecCategoryCode() : "");
            keys.append(ObjectUtil.isNotNull(item.getTerCategoryCode()) ? item.getTerCategoryCode() : "");
            keys.append(ObjectUtil.isNotNull(item.getProvinceCode()) ? item.getProvinceCode() : "");
            keys.append(ObjectUtil.isNotNull(item.getCityCode()) ? item.getCityCode() : "");
            keys.append(ObjectUtil.isNotNull(item.getCountyCode()) ? item.getCountyCode() : "");
            if (CollectionUtils.isNotEmpty(skuCodeList)) {
                keys.append(ObjectUtil.isNotNull(item.getSkuCode()) ? item.getSkuCode() : "");
            }
            item.setCondition(keyStr.toString());
        });
        return salesPlan;
    }

    /**
     * 获取分组条件
     *
     * @param salesPlanOtherDTO
     * @return
     */
    public List<String> getConditions(SalesPlanOtherDTO salesPlanOtherDTO) {
        List<String> conditions = new ArrayList<>();
        if (CollectionUtils.isEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            conditions.add(BaseSearchColumnEnum.CHANNEL_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            conditions.add(BaseSearchColumnEnum.SUB_CHANNEL_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getProvinceCodeList())) {
            conditions.add(BaseSearchColumnEnum.PROVINCE_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getCityCodeList())) {
            conditions.add(BaseSearchColumnEnum.CITY_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getCountyCodeList())) {
            conditions.add(BaseSearchColumnEnum.COUNTY_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getStoreCodeList())) {
            conditions.add(BaseSearchColumnEnum.STORE_CODE.getColumn());
        }
        if (!CollectionUtils.isEmpty(salesPlanOtherDTO.getPriCategoryCodeList())) {
            conditions.add(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getSecCategoryCodeList())) {
            conditions.add(BaseSearchColumnEnum.SEC_CATEGORY_CODE.getColumn());
        }
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTO.getTerCategoryCodeList())) {
            conditions.add(BaseSearchColumnEnum.TER_CATEGORY_CODE.getColumn());
        }
        if (!CollectionUtils.isEmpty(salesPlanOtherDTO.getSkuCodeList())) {
            conditions.add(BaseSearchColumnEnum.SKU_CODE.getColumn());
        }
        return conditions;
    }

    /**
     * 计算比例
     *
     * @param salesPlan   结果列表
     * @param skuUnitList sku单位列表
     * @return {@link List<DemandPlanDTO>}
     */
    private List<SalesPlanOtherDTO> calculationPro(List<SalesPlanOtherDTO> salesPlan, List<SkuUnitDTO> skuUnitList) {
        skuUnitList.forEach(skuUnit -> {
            salesPlan.forEach(item -> {
                if (item.getSkuCode().equals(skuUnit.getSkuCode())) {
                    Double scale = skuUnit.getScale();
                    item.setAllchannelConfirmedQty(item.getAllchannelConfirmedQty().divide(BigDecimal.valueOf(scale), 7, BigDecimal.ROUND_HALF_UP));
                    item.setActualReceiveQty(item.getActualReceiveQty().divide(BigDecimal.valueOf(scale), 7, BigDecimal.ROUND_HALF_UP));
                    item.setActualSalesQty(item.getActualSalesQty().divide(BigDecimal.valueOf(scale), 7, BigDecimal.ROUND_HALF_UP));
                }
            });
        });
        return salesPlan;
    }


    /**
     * 查询全渠道其他渠道计划_目标与销售计划差异(范围)
     *
     * @param salesPlanOtherDTO
     * @return
     */
    @Override
    public List<SalesPlanOtherDifferinInfoDTO> listAllByCycles(SalesPlanOtherDTO salesPlanOtherDTO) {
        //如果开始时间为空
        this.dealBeginAndEndTime(salesPlanOtherDTO);
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(salesPlanOtherDTO.getStartTime(), (int) DateUtil.betweenWeek(salesPlanOtherDTO.getStartTime(), salesPlanOtherDTO.getEndTime(), false));
        salesPlanOtherDTO.setWeekDateList(weekDates);
        Long userId = salesPlanOtherDTO.getCreator();
        //获取当前用户角色权限
        List<RoleAuthorityAreaDTO> roleAreaList = roleAuthorityAreaRepository.listByUserId(userId);
        if (CollectionUtils.isEmpty(roleAreaList)) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        //渠道不为空为其他渠道计划用户
        roleAreaList = roleAreaList.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelCode())).collect(Collectors.toList());
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getChannelCode();
            channels.add(channel);
        });
        //高级搜索不选择渠道，查询用户对应渠道
        if (CollectionUtils.isEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            salesPlanOtherDTO.setChannelCodeList(channels);
        }

        List<SalesPlanOtherDTO> salesPlanOtherDTOList = salesPlanOtherRespository.listAllByDifferentCycles(salesPlanOtherDTO);
        if (CollectionUtils.isNotEmpty(salesPlanOtherDTOList)) {
            //todo 大数据的数据暂时给死值
            salesPlanOtherDTOList.forEach(item -> {
                item.setActualReceiveQty(new BigDecimal(423));
                item.setActualSalesQty(new BigDecimal(450));
                item.setConfirmAmount(item.getAllchannelConfirmedQty().multiply(BigDecimal.TEN));
                item.setActualSalesAmount(item.getActualSalesQty().multiply(BigDecimal.TEN));
            });
            if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOtherDTO.getUnitType())) {
                List<String> skuCodes = salesPlanOtherDTOList.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
                //处理单位
                List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodes, salesPlanOtherDTO.getUnitType());
                this.calculationPro(salesPlanOtherDTOList, skuUnitList);
            }
            //设置分组的key
            Map<String, List<SalesPlanOtherDTO>> listMap = salesPlanOtherDTOList.stream().collect(Collectors.groupingBy(item -> CommonConstants.ONE.toString(), Collectors.toList()));
            //实际收货量
            List<SalesPlanOtherDifferinInfoDTO> targetList = this.getTargetList(listMap, salesPlanOtherDTO);
            //处理查询出来的条数和数据，查询明细指标的条件
//            Map<String, Map<Date, BigDecimal>> gmvTarget = this.dealGmvTarget(demandPlanDO, demandPlan);
//            //销售目标（金额）
//            List<BigDecimal> salesTargetAmounts=new ArrayList<>();
//            gmvTarget.forEach((k,v)->salesTargetAmounts.addAll(v.values()));
            //目标达成率（金额）
//            List<BigDecimal> targetAcrateAmounts=new ArrayList<>();
//            List<BigDecimal> actualSalesAmounts = targetList.get(0).getActualSalesAmounts();
//            for (int i=0;i<actualSalesAmounts.size();i++){
//                if(salesTargetAmounts.get(i).compareTo(BigDecimal.ZERO)==0){
//                    targetAcrateAmounts.add(BigDecimal.ZERO);
//                }else{
//                    targetAcrateAmounts.add(actualSalesAmounts.get(i).divide(salesTargetAmounts.get(i),BigDecimal.ROUND_UP ,5 ).multiply(new BigDecimal(100)));
//                }
//            }
            //GMV指标
            targetList.forEach(item -> {
                item.setActualReceivedQtyLabel(SalesPlanOtherDifferinEnum.ACTUAL_RECEIVED_QTY.getDesc());
                //item.setSalesTargetAmounts(salesTargetAmounts);
                //item.setSalesTargetAmountLabel(SalesPlanOtherDifferinEnum.SALES_TARGET_AMOUNT.getDesc());
                //item.setTargetAcrateAmounts(targetAcrateAmounts);
                //item.setTargetAcrateAmountLabel(SalesPlanOtherDifferinEnum.TARGET_ACRATE_AMOUNT.getDesc());
            });
            return targetList;
        }

        return null;
    }

    /**
     * 处理时间
     */
    public SalesPlanOtherDTO dealBeginAndEndTime(SalesPlanOtherDTO salesPlanOtherDTO) {
        //如果开始时间为空
        if (ObjectUtil.isEmpty(salesPlanOtherDTO.getStartTime())) {
            salesPlanOtherDTO.setStartTime(DateUtil.beginOfWeek(new Date()));
        } else {
            salesPlanOtherDTO.setStartTime(DateUtil.beginOfWeek(salesPlanOtherDTO.getStartTime()));
        }
        //如果结束时间为空
        if (ObjectUtil.isEmpty(salesPlanOtherDTO.getEndTime())) {
            salesPlanOtherDTO.setEndTime(DateUtil.beginOfWeek(DateUtil.offsetWeek(new Date(), CommonConstants.WEEK_TARGET_SIZE)));
        } else {
            salesPlanOtherDTO.setEndTime(DateUtil.beginOfWeek(DateUtil.offsetWeek(salesPlanOtherDTO.getEndTime(), CommonConstants.ONE)));
        }
        return salesPlanOtherDTO;
    }

    /**
     * 导出所有查询数据
     *
     * @param salesPlanOtherDTO
     * @param type
     * @throws Exception
     */
    @Override
    public ExcelExportDataDTO export(SalesPlanOtherDTO salesPlanOtherDTO, Integer type) throws Exception {
        //指标名称集合
        List<String> allTargetsDesc = SalesPlanOtherDifferinEnum.getAllTargetsDesc();

        //获取日期标题
        List<String> dateTitles = MyDateUtil.processCyclesDate(salesPlanOtherDTO.getWeekDateList(), "MM.dd");
        //增加合计
        dateTitles.add("合计");
        Long userId = salesPlanOtherDTO.getCreator();
        //获取当前用户角色权限
        List<RoleAuthorityAreaDTO> roleAreaList = roleAuthorityAreaRepository.listByUserId(userId);
        if (CollectionUtils.isEmpty(roleAreaList)) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        //渠道不为空为其他渠道计划用户
        roleAreaList = roleAreaList.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelCode())).collect(Collectors.toList());
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getChannelCode();
            channels.add(channel);
        });
        //高级搜索不选择渠道，查询用户对应渠道
        if (CollectionUtils.isEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            salesPlanOtherDTO.setChannelCodeList(channels);
        }
        List<SalesPlanOtherDTO> salesPlanOtherDTOList = new ArrayList<>();
        List<List<Object>> exportDataList = null;
        //全部数据导出
        if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            salesPlanOtherDTOList = salesPlanOtherRespository.listAllByConditionDifferent(salesPlanOtherDTO);
        }
        //当前页数据导出
        if (ExcelExportTypeEnum.CURRENT_PAGE_EXPORT.getType().equals(type)) {
            List<SalesPlanOtherDO> list = null;//salesPlanOtherRespository.listWeekBySelective(salesPlanOtherDTO).getList();
            if (ObjectUtil.isNotEmpty(list)) {
                //处理查询出来的条数和数据，查询明细指标的条件
                SalesPlanOtherDO salesPlanOtherDO = this.dealData(list, salesPlanOtherDTO);
                salesPlanOtherDTOList = salesPlanOtherRespository.listSalesAndTargetDifferent(salesPlanOtherDO);
            }
        }
        //导出选中的数据
        if (ExcelExportTypeEnum.CHECKED_BOX_EXPORT.getType().equals(type)) {
            SalesPlanOtherDO salesPlanOtherDO = dealData(salesPlanOtherConvertor.dtoToDO(salesPlanOtherDTO.getSalesPlanOtherList()), salesPlanOtherDTO);
            salesPlanOtherDTOList = salesPlanOtherRespository.listSalesAndTarget(salesPlanOtherDO);
        }
        if (CollectionUtils.isEmpty(salesPlanOtherDTOList)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
        }
        //todo 大数据的数据暂时给死值
        salesPlanOtherDTOList.forEach(item -> {
            item.setActualReceiveQty(new BigDecimal(423));
            item.setActualSalesQty(new BigDecimal(450));
            item.setConfirmAmount(item.getAllchannelConfirmedQty().multiply(BigDecimal.TEN));
            item.setActualSalesAmount(item.getActualSalesQty().multiply(BigDecimal.TEN));
        });
        if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOtherDTO.getUnitType())) {
            List<String> skuCodeList = salesPlanOtherDTOList.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
            //处理单位
            List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, salesPlanOtherDTO.getUnitType());
            this.calculationPro(salesPlanOtherDTOList, skuUnitList);
        }
        //获取所有查询条件标识
        List<String> conditions = this.getConditions(salesPlanOtherDTO);
        //设置分组依据的key值
        this.getGroupByKey(salesPlanOtherDTOList, salesPlanOtherDTO.getSkuCodeList(), conditions);
        //将数据分组
        Map<String, List<SalesPlanOtherDTO>> listMap = salesPlanOtherDTOList.stream().collect(Collectors.groupingBy(SalesPlanOtherDTO::getCondition, Collectors.toList()));
        List<SalesPlanOtherDifferinInfoDTO> targetList = this.getTargetList(listMap, salesPlanOtherDTO);

        //处理对应的GMV指标
//        Map<String, Map<Date, BigDecimal>> gmvTarget = this.dealGmvTarget(demandPlanDO, demandPlan);
//        this.putTargetInList(targetList,demandPlan ,gmvTarget ,weekDates , conditions);
        //全部数据导出
        exportDataList = this.getExcelTargetList(targetList, allTargetsDesc, dateTitles);
        //获取excel标题 同时返回高级搜索标题的数量
        List<List<String>> heads = new ArrayList<>();
        int mergeCellsColumns = this.setExcelTitles(heads, conditions, dateTitles);
        return ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, heads, allTargetsDesc.size(), new GeneralCellWriteHandler());
    }

    /**
     * 汇总分组后的数据
     *
     * @param paramMap          参数映射
     * @param salesPlanOtherDTO 其他渠道计划
     * @return {@link List<SalesPlanOtherDifferinInfoDTO>}
     */
    private List<SalesPlanOtherDifferinInfoDTO> getTargetList(Map<String, List<SalesPlanOtherDTO>> paramMap, SalesPlanOtherDTO salesPlanOtherDTO) {
        List<SalesPlanOtherDifferinInfoDTO> salesPlanOtherAccuracyInfoList = new ArrayList<>();
        List<Map<String, Date>> weekDateList = salesPlanOtherDTO.getWeekDateList();
        //格式化百分比用
        NumberFormat percent = NumberFormat.getPercentInstance();
        percent.setMaximumFractionDigits(3);

        //将分组后的数据汇总
        paramMap.keySet().forEach(key -> {
            List<BigDecimal> salesConfirmAmounts = new ArrayList<>();
            List<BigDecimal> actualSalesAmounts = new ArrayList<>();
            List<BigDecimal> actualSalesQtys = new ArrayList<>();
            List<BigDecimal> salesConfirmQtys = new ArrayList<>();
            List<BigDecimal> actualReceivedQtys = new ArrayList<>();
            SalesPlanOtherDifferinInfoDTO salesPlanOtherDifferentInfo = new SalesPlanOtherDifferinInfoDTO();
            // 设置销售计划确认量（数量）
            weekDateList.forEach(date -> salesConfirmQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get(DemandPlanEnum.START_TIME.getColumns())) == 0 && item.getPlanEndDate().compareTo(date.get(DemandPlanEnum.END_TIME.getColumns())) == 0).map(SalesPlanOtherDTO::getAllchannelConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherDifferentInfo.setSalesConfirmQtyLabel(SalesPlanOtherDifferinEnum.SALES_CONFIRM_QTY.getDesc());
            salesPlanOtherDifferentInfo.setSalesConfirmQtys(salesConfirmQtys);

            //设置销售计划确认量（金额）销售计划确认量乘单价
            weekDateList.forEach(date -> salesConfirmAmounts.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get(DemandPlanEnum.START_TIME.getColumns())) == 0 && item.getPlanEndDate().compareTo(date.get(DemandPlanEnum.END_TIME.getColumns())) == 0).map(SalesPlanOtherDTO::getConfirmAmount).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherDifferentInfo.setSalesConfirmAmounts(salesConfirmAmounts);
            salesPlanOtherDifferentInfo.setSalesConfirmAmountLabel(SalesPlanOtherDifferinEnum.SALES_CONFIRM_AMOUNT.getDesc());

            //实际销售数量
            weekDateList.forEach(date -> actualSalesQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get(DemandPlanEnum.START_TIME.getColumns())) == 0 && item.getPlanEndDate().compareTo(date.get(DemandPlanEnum.END_TIME.getColumns())) == 0).map(SalesPlanOtherDTO::getActualSalesQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherDifferentInfo.setActualSalesQtyLabel(SalesPlanOtherDifferinEnum.ACTUAL_SALES_QTY.getDesc());
            salesPlanOtherDifferentInfo.setActualSalesQtys(actualSalesQtys);

            //实际销售金额
            weekDateList.forEach(date -> actualSalesAmounts.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get(DemandPlanEnum.START_TIME.getColumns())) == 0 && item.getPlanEndDate().compareTo(date.get(DemandPlanEnum.END_TIME.getColumns())) == 0).map(SalesPlanOtherDTO::getActualSalesAmount).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherDifferentInfo.setActualSalesAmountLabel(SalesPlanOtherDifferinEnum.ACTUAL_SALES_AMOUNT.getDesc());
            salesPlanOtherDifferentInfo.setActualSalesAmounts(actualSalesAmounts);

            // 实际收货量
            weekDateList.forEach(date -> actualReceivedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get(DemandPlanEnum.START_TIME.getColumns())) == 0 && item.getPlanEndDate().compareTo(date.get(DemandPlanEnum.END_TIME.getColumns())) == 0).map(SalesPlanOtherDTO::getActualReceiveQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherDifferentInfo.setActualReceivedQtys(actualReceivedQtys);
            salesPlanOtherDifferentInfo.setActualReceivedQtyLabel(SalesPlanOtherDifferinEnum.ACTUAL_RECEIVED_QTY.getDesc());
            //获取渠道、区域、商品信息
            this.getInfoData(paramMap.get(key), salesPlanOtherDifferentInfo, salesPlanOtherDTO.getSkuCodeList(), salesPlanOtherDTO);
            salesPlanOtherAccuracyInfoList.add(salesPlanOtherDifferentInfo);
        });
        return salesPlanOtherAccuracyInfoList;
    }

    /**
     * 获取渠道、区域、商品信息
     *
     * @param salesPlanOthers
     * @param salesPlanOtherDifferinInfo
     * @param skuCodeList
     * @return
     */
    private SalesPlanOtherDifferinInfoDTO getInfoData(List<SalesPlanOtherDTO> salesPlanOthers, SalesPlanOtherDifferinInfoDTO salesPlanOtherDifferinInfo, List<String> skuCodeList, SalesPlanOtherDTO salesPlanOtherDTO) {
        /**
         * 区域信息
         */
        salesPlanOtherDifferinInfo.setArea(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getProvinceName())).map(SalesPlanOtherDTO::getProvinceName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getCityName())).map(e -> "/" + e.getCityName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getCountyName())).map(e -> "/" + e.getCountyName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(salesPlanOtherDTO.getStoreCodeList())).map(e -> "/" + e.getStoreName()).distinct().collect(Collectors.joining()));
        // 渠道信息
        salesPlanOtherDifferinInfo.setChannel(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelName())).map(SalesPlanOtherDTO::getChannelName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSubChannelName())).map(e -> "/" + e.getSubChannelName()).distinct().collect(Collectors.joining()));
        // 品类信息
        salesPlanOtherDifferinInfo.setCategory(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getPriCategoryName())).map(SalesPlanOtherDTO::getPriCategoryName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSecCategoryName())).map(e -> "/" + e.getSecCategoryName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getTerCategoryName())).map(e -> "/" + e.getTerCategoryName()).distinct().collect(Collectors.joining()));
        //sku信息
        if (CollectionUtils.isNotEmpty(skuCodeList)) {
            salesPlanOtherDifferinInfo.setSkuCode(salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuCode())).map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.joining()));
            salesPlanOtherDifferinInfo.setSkuName(salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuName())).map(SalesPlanOtherDTO::getSkuName).distinct().collect(Collectors.joining()));
        }
        //一级渠道
        salesPlanOtherDifferinInfo.setChannelCode(salesPlanOthers.get(0).getChannelCode());
        salesPlanOtherDifferinInfo.setSubChannelCode(salesPlanOthers.get(0).getSubChannelCode());
        salesPlanOtherDifferinInfo.setPriCategoryCode(salesPlanOthers.get(0).getPriCategoryCode());
        salesPlanOtherDifferinInfo.setSecCategoryCode(salesPlanOthers.get(0).getSecCategoryCode());
        salesPlanOtherDifferinInfo.setTerCategoryCode(salesPlanOthers.get(0).getSecCategoryCode());
        salesPlanOtherDifferinInfo.setStoreCode(ObjectUtil.isEmpty(salesPlanOtherDTO.getStoreCodeList()) ? null : salesPlanOthers.get(CommonConstants.ZERO).getStoreCode());
        salesPlanOtherDifferinInfo.setProvinceCode(salesPlanOthers.get(0).getProvinceCode());
        salesPlanOtherDifferinInfo.setCityCode(salesPlanOthers.get(0).getCityCode());
        salesPlanOtherDifferinInfo.setCountyCode(salesPlanOthers.get(0).getCountyCode());

        return salesPlanOtherDifferinInfo;
    }

    /**
     * Excel中的每条数据
     *
     * @param targets
     * @param dateTitles
     * @return
     */
    private List<List<Object>> getExcelTargetList(List<SalesPlanOtherDifferinInfoDTO> targetList, List<String> targets, List<String> dateTitles) {
        //格式化百分比用
        NumberFormat percent = NumberFormat.getPercentInstance();
        percent.setMaximumFractionDigits(3);
        List<List<Object>> exportDataList = new ArrayList<>();
        //将分组后的数据汇总
        targetList.forEach(item -> {
            //获取渠道、区域、商品信息
            for (int i = 0; i < targets.size(); i++) {
                List<Object> itemRow = new ArrayList<>();
                //加入渠道，区域，品类，商品  信息
                this.setExcelRowAdvancedSearchCondition(item, itemRow);
                //加入指标
                itemRow.add(targets.get(i));
                //加入数据
                for (int j = 0; j < (dateTitles.size() - 1); j++) {
                    //获取指标集合，这里没有排序，默认使用枚举的顺序
                    switch (i) {
//                        case 0:
//                            itemRow.add(item.getSalesTargetAmounts().get(j).compareTo(BigDecimal.ZERO)==0?"-":item.getSalesTargetAmounts().get(j));
//                            break;
                        case 0:
                            itemRow.add(item.getSalesConfirmAmounts().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : item.getSalesConfirmAmounts().get(j));
                            break;
                        case 1:
                            itemRow.add(item.getActualSalesAmounts().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : item.getActualSalesAmounts().get(j));
                            break;
                        case 2:
                            itemRow.add(item.getActualSalesQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : item.getActualSalesQtys().get(j));
                            break;
                        case 3:
                            itemRow.add(item.getSalesConfirmQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : item.getSalesConfirmQtys().get(j));
                            break;
//                        case 4:
//                            itemRow.add(item.getTargetAcrateAmounts().get(j).compareTo(BigDecimal.ZERO)==0?"-":item.getTargetAcrateAmounts().get(j));
//                            break;
                        case 4:
                            itemRow.add(item.getActualReceivedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : item.getActualReceivedQtys().get(j));
                            break;
                        default:
                            break;
                    }
                }
                //合计
                BigDecimal total = BigDecimal.ZERO;
                //获取除日期外的下标
                int index = itemRow.size() - (dateTitles.size() - 1);
                List<Object> numRow = new ArrayList<>();
                numRow.addAll(itemRow);
                for (int a = 0; a < index; a++) {
                    numRow.remove(numRow.get(0));
                }
                //循环增加查询的日期对应指标数量
                for (Object obj : numRow) {
                    BigDecimal num = BigDecimal.ZERO;
                    if ("-".equals(obj)) {
                        num = BigDecimal.ZERO;
                    } else {
                        num = new BigDecimal(obj.toString());
                    }
                    total = total.add(num);
                }
                itemRow.add(total.equals(BigDecimal.ZERO) ? "-" : total);
                exportDataList.add(itemRow);
            }
        });
        return exportDataList;
    }

    /**
     * excel每行数据设置 高级搜索  信息
     *
     * @param salesPlanOtherDifferinInfo
     * @param itemRow
     * @return void
     **/
    private void setExcelRowAdvancedSearchCondition(SalesPlanOtherDifferinInfoDTO salesPlanOtherDifferinInfo, List<Object> itemRow) {
        if (!StringUtils.isEmpty(salesPlanOtherDifferinInfo.getChannel())) {
            itemRow.add(salesPlanOtherDifferinInfo.getChannel());
        }
        if (!StringUtils.isEmpty(salesPlanOtherDifferinInfo.getArea())) {
            itemRow.add(salesPlanOtherDifferinInfo.getArea());
        }
        if (!StringUtils.isEmpty(salesPlanOtherDifferinInfo.getCategory())) {
            itemRow.add(salesPlanOtherDifferinInfo.getCategory());
        }
        if (!StringUtils.isEmpty(salesPlanOtherDifferinInfo.getSkuName())) {
            itemRow.add(salesPlanOtherDifferinInfo.getSkuCode() + "/" + salesPlanOtherDifferinInfo.getSkuName());
        }
    }


    private int setExcelTitles(List<List<String>> heads, List<String> conditions, List<String> dateTitles) {
        //获取高级搜索标题
        this.getExcelAdvancedSearchTitle(heads, conditions);
        int result = heads.size();
        //加入指标标题
        List<String> targetTitle = new ArrayList<>();
        targetTitle.add(ExcelExportTitleEnum.TARGET_TITLE.getTitle());
        heads.add(targetTitle);
        //加入日期标题
        AdvancedSearchUtil.getExcelDateTitle(heads, dateTitles);
        return result;
    }

    /**
     * Excel表头
     *
     * @param heads
     * @param conditions
     */
    private void getExcelAdvancedSearchTitle(List<List<String>> heads, List<String> conditions) {
        if (conditions.contains(BaseSearchColumnEnum.CHANNEL_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.SUB_CHANNEL_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.CITY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.COUNTY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.STORE_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.SEC_CATEGORY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.TER_CATEGORY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.SKU_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.SKU_TITLE.getTitle());
        }
    }

    /**
     * 获取标题行list
     *
     * @param heads
     * @param title
     */
    private static void setList(List<List<String>> heads, String title) {
        List<String> list = new ArrayList<>();
        list.add(title);
        heads.add(list);
    }

    /**
     * 把实际收货量，销售目标，目标达成率放进数组中
     */
    private List<SalesPlanOtherDifferinInfoDTO> putTargetInList(List<SalesPlanOtherDifferinInfoDTO> targetList, DemandPlanDTO demandPlan
            , Map<String, Map<Date, BigDecimal>> gmvTarget,
                                                                List<Map<String, Date>> weekDates, List<String> conditions) {
        targetList.forEach(item -> {
            //销售目标(金额)
            List<BigDecimal> salesTargetAmounts = new ArrayList<>();
            //目标达成率(金额) 实际销售额/ 目标销售额
            List<BigDecimal> targetAcRateQtys = new ArrayList<>();
            //判断是否需要查询GMV表中的指标
            if (demandPlan.getValidGmv()) {
                String str = this.dealGroupCondition(conditions, item);
                Map<Date, BigDecimal> salesTargetAmountsMap = gmvTarget.get(str);
                if (ObjectUtil.isEmpty(salesTargetAmountsMap)) {
                    weekDates.forEach(date -> salesTargetAmounts.add(BigDecimal.ZERO));
                    weekDates.forEach(date -> targetAcRateQtys.add(BigDecimal.ZERO));
                } else {
                    salesTargetAmounts.addAll(salesTargetAmountsMap.values());
                    for (int i = 0; i < salesTargetAmounts.size(); i++) {
                        List<BigDecimal> actualSalesAmounts = item.getActualSalesAmounts();
                        if (salesTargetAmounts.get(i).compareTo(BigDecimal.ZERO) == 0) {
                            targetAcRateQtys.add(BigDecimal.ZERO);
                        } else {
                            targetAcRateQtys.add(actualSalesAmounts.get(i).divide(salesTargetAmounts.get(i), BigDecimal.ROUND_HALF_UP, 7));
                        }
                    }
                }
            }
            //如果不需要查询，给赋值-1，前端显示为—
            else {
                weekDates.forEach(date -> salesTargetAmounts.add(new BigDecimal(-1)));
                weekDates.forEach(date -> targetAcRateQtys.add(new BigDecimal(-1)));
            }
            item.setSalesTargetAmounts(salesTargetAmounts);
            //item.setSalesTargetAmountLabel(SalesPlanOtherDifferinEnum.SALES_TARGET_AMOUNT.getDesc());
            item.setTargetAcrateAmounts(targetAcRateQtys);
            //item.setTargetAcrateAmountLabel(SalesPlanOtherDifferinEnum.TARGET_ACRATE_AMOUNT.getDesc());

        });
        return targetList;
    }


    /**
     * 处理最后的分组条件
     */
    private String dealGroupCondition(List<String> condition, SalesPlanOtherDifferinInfoDTO infoDTO) {
        StringBuilder keys = new StringBuilder();
        if (condition.contains(BaseSearchColumnEnum.CHANNEL_CODE.getColumn())) {
            keys.append(infoDTO.getChannelCode());
        }
        if (condition.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            keys.append(infoDTO.getProvinceCode());
        }
        if (condition.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            keys.append(infoDTO.getPriCategoryCode());
        }
        return keys.toString();
    }

    /**
     * 处理需要查询的数据
     *
     * @param list              列表
     * @param salesPlanOtherDTO 需求计划
     * @return {@link DemandPlanDO}
     */
    private SalesPlanOtherDO dealData(List<SalesPlanOtherDO> list, SalesPlanOtherDTO salesPlanOtherDTO) {
        //把查询的结果代入新的对象中，用于查询数据
        SalesPlanOtherDO salesPlanOther = new SalesPlanOtherDO();
        if (ObjectUtil.isNotEmpty(list)) {
            salesPlanOther.setChannelCode(list.get(0).getChannelCode());
            salesPlanOther.setSubChannelCode(list.get(0).getSubChannelCode());
            salesPlanOther.setProvinceCode(list.get(0).getProvinceCode());
            salesPlanOther.setCityCode(list.get(0).getCityCode());
            salesPlanOther.setCountyCode(list.get(0).getCountyCode());
            salesPlanOther.setPriCategoryCode(list.get(0).getPriCategoryCode());
            salesPlanOther.setSecCategoryCode(list.get(0).getSecCategoryCode());
            salesPlanOther.setTerCategoryCode(list.get(0).getTerCategoryCode());
            salesPlanOther.setSkuCode(list.get(0).getSkuCode());
            salesPlanOther.setStoreCode(list.get(0).getStoreCode());
            salesPlanOther.setSalesPlanOtherList(list);
        }
        salesPlanOther.setStartTime(DateUtil.beginOfWeek(salesPlanOtherDTO.getStartTime()));
        salesPlanOther.setEndTime(salesPlanOtherDTO.getEndTime());
        return salesPlanOther;
    }

    /**
     * 组织的关键
     * 获取分组条件
     *
     * @param gmvTargetDTOS 列表
     * @param gmvTargetDTOS gmv目标dto
     * @return {@link String}
     */
    private void groupKey(List<GmvTargetDTO> gmvTargetDTOS) {
        gmvTargetDTOS.forEach(item -> {
            StringBuilder conditions = new StringBuilder();
            conditions.append(ObjectUtil.isNotEmpty(item.getChannelCode()) ? item.getChannelCode() : "");
            conditions.append(ObjectUtil.isNotEmpty(item.getProvinceCode()) ? item.getProvinceCode() : "");
            conditions.append(ObjectUtil.isNotEmpty(item.getPriCategoryCode()) ? item.getPriCategoryCode() : "");
            item.setGroupKey(conditions.toString());
        });
    }


    /**
     * 处理GMV指标
     *
     * @param demandPlanDO 需求计划
     */
    private Map<String, Map<Date, BigDecimal>> dealGmvTarget(DemandPlanDO demandPlanDO, DemandPlanDTO demandPlanDTO) {
        List<GmvTargetDTO> gmvTargetDTOS = gmvTargetRepository.listSaleTarget(demandPlanDO);
        Map<String, Map<Date, BigDecimal>> gmvTarget = new LinkedHashMap<>();
        //先分组，按照查询条件进行分组
        this.groupKey(gmvTargetDTOS);
        Map<String, List<GmvTargetDTO>> listMap = gmvTargetDTOS.stream().collect(Collectors.groupingBy(GmvTargetDTO::getGroupKey, Collectors.toList()));
        //判断本周的周末是否在这个月中
        listMap.forEach((k, v) -> {
            Map<Date, BigDecimal> dateListMap = new LinkedHashMap<>();
            demandPlanDTO.getWeekDateList().forEach(date -> {
                //计算出
                Map<Date, BigDecimal> decimalMap = MyDateUtil.dealCrossMonth(date.get(DemandPlanEnum.END_TIME.getColumns()));
                //此种情况是查询出当前时间在这个月内的前一部分
                BigDecimal decimal = v.stream().filter(
                        item -> item.getPlanEndDate().getTime() >= date.get(DemandPlanEnum.END_TIME.getColumns()).getTime() &&
                                item.getPlanEndDate().getTime() <= DateUtil.endOfMonth(date.get(DemandPlanEnum.END_TIME.getColumns())).getTime()).map(GmvTargetDTO::getGmvTarget).reduce(BigDecimal.ZERO, BigDecimal::add)
                        .multiply(decimalMap.get(date.get(DemandPlanEnum.END_TIME.getColumns())).setScale(BigDecimal.ROUND_HALF_UP, 7));
                //此种情况是计算出最后一周出现跨月的情况，计算出比例
                BigDecimal bigDecimal = v.stream().filter(item -> item.getPlanEndDate().getTime() >= date.get(DemandPlanEnum.START_TIME.getColumns()).getTime() &&
                        item.getPlanEndDate().getTime() <= date.get(DemandPlanEnum.END_TIME.getColumns()).getTime()).map(GmvTargetDTO::getGmvTarget).
                        reduce(BigDecimal.ZERO, BigDecimal::add).multiply(BigDecimal.ONE.subtract(decimalMap.get(date.get(DemandPlanEnum.END_TIME.getColumns()))).setScale(BigDecimal.ROUND_HALF_UP, 7));
                dateListMap.put(date.get(DemandPlanEnum.START_TIME.getColumns()), decimal.add(bigDecimal));
            });
            gmvTarget.put(k, dateListMap);
        });
        return gmvTarget;
    }

    @Override
    public void delete(String opSign) {
        salesPlanOtherDifferinRespository.delete(opSign);
    }
}
